package mc.support.task.mgr;

import mc.support.task.common.CronTask;
import mc.support.util.PlainUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/**
 * Created with IntelliJ IDEA. <br/>
 * Author: Francis Yun    <br/>
 * Date: 2014-06-04  <br/>
 */
public class TaskLoader implements ApplicationContextAware {

    private static Logger log = LoggerFactory.getLogger( TaskLoader.class );

    private ApplicationContext context;

    private TaskExecutor taskExecutor = new TaskExecutor();

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.context = context;
    }

    public boolean loadTasks() {
        if ( null != context ) {
            Map<String, CronTask>  cronTasks = context.getBeansOfType( CronTask.class );
            if ( null != cronTasks ) {
                for ( Map.Entry<String, CronTask> e : cronTasks.entrySet() ) {
                    String taskName = e.getKey();
                    CronTask task = e.getValue();
                    if ( null != task ) {
                        launchSingleTask( taskName, task );
                    }
                }
            }
            taskExecutor.startScheduler();
            return true;
        }
        return false;
    }

    public void unloadTasks() {
        taskExecutor.close();
    }

    private void launchSingleTask(String taskName, CronTask task) {
        try {
            if ( task.isLaunchNow() ) {
                taskExecutor.submit( task );
                log.info( "Task : {} launched successfully! ", taskName );
            }
            if ( task.needsSchedule() ) {
                String pat = task.getCronPattern();
                taskExecutor.schedule( pat, task );
                log.info( " Task : {} scheduled at pattern: {} ",
                        new Object[] { taskName, pat } );
            }
        } catch (Exception ex) {
            log.error( "Task : {} start fail: {}",
                    new Object[] { taskName, PlainUtil.getStackTrace( ex )} );
        }
    }

}
